package com.trust.util;

import com.trust.agri.exception.ServiceException;
import com.trust.annotation.NotNull;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/**
 * @author ccc
 * @desc
 * @since 2023/12/15 15:01
 */
public class NullCheck {

    // 对指定对象进行空指针校验。返回true表示该对象跟它的每个字段都非空，返回false表示对象为空或者至少一个字段为空
    public static boolean isValid(Object obj) {
        if (obj == null) {
            System.out.println("校验对象为空");
            return false;
        }
        Class cls = obj.getClass(); // 获得对象实例的基因类型
        // 声明一个字符串清单，用来保存非空校验失败的无效字段名称
        List<String> invalidList = new ArrayList<String>();
        // 获取对象的所有属性（如果使用getFields，就无法获取到private的属性）
        Field[] fields = cls.getDeclaredFields();

        for (Field field : fields) { // 依次遍历每个对象属性
            // 如果该属性声明了NotNull注解，就进行字段非空的校验
            if (field.isAnnotationPresent(NotNull.class)) {
                if (field != null) {
                    field.setAccessible(true); // 将该字段设置为允许访问
                    Object value = null; // 获取某实例的字段值
                    try {
                        value = field.get(obj);
                    } catch (IllegalAccessException e) {
                        throw new ServiceException("获取字段失败");
                    }
                    if (null == value || StringUtils.isBlank(value.toString())) { // 如果发现该字段为空
                        // 就把该字段的名称添加到无效清单中
                        //invalidList.add(field.getName());
                        throw new ServiceException(String.format("%s 不能为空", field.getAnnotation(NotNull.class).name()));
                    }
                }
            }
        }
        if (invalidList.size() > 0) { // 无效清单非空，表示至少有一个字段没通过非空校验
            String desc = String.format("不能为空的字段有：%s",
                    invalidList.toString());
            throw new ServiceException(desc);
        } else {
            return true;
        }
    }
}
